package com.ds.common.graceful;

import com.alibaba.nacos.api.naming.NamingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@RestController
@ConditionalOnProperty(prefix = "ds.graceful", name = "enabled", havingValue = "true", matchIfMissing = true)
public class GracefulShutdown {

    private final NacosDiscoveryProperties nacosDiscoveryProperties;
    private final Environment environment;
    private final ApplicationContext applicationContext;

    @Autowired
    public GracefulShutdown(ApplicationContext applicationContext, NacosDiscoveryProperties nacosDiscoveryProperties, Environment environment) {
        this.nacosDiscoveryProperties = nacosDiscoveryProperties;
        this.environment = environment;
        this.applicationContext = applicationContext;
    }

    @GetMapping("/gracefulShutdown")
    public String stopEureka(HttpServletRequest request) {
        String remoteAddr = request.getRemoteAddr();
        if ("127.0.0.1".equals(remoteAddr) || "0:0:0:0:0:0:0:1".equals(remoteAddr)) {
            nacosShutdown();
            eurekaShutdown();
            return "done";
        } else {
            return "只能本地执行该操作";
        }

    }

    private void nacosShutdown() {
        try {
            String serviceName = environment.getProperty("spring.cloud.nacos.discovery.service");
            if (serviceName == null || serviceName.isEmpty()) {
                serviceName = nacosDiscoveryProperties.getService();
            }
            NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
            namingService.deregisterInstance(serviceName, nacosDiscoveryProperties.getIp(), nacosDiscoveryProperties.getPort());
            System.out.println("==================nacos shutdown success ==============================");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("==================nacos shutdown fail ==============================");
        }
    }

    /**
     * 目前是正在从eureka迁移到nacos 因此有可能有些应用没有 EurekaClient
     */
    private void eurekaShutdown() {
        try {
            Class<?> eurekaClass = Class.forName("com.netflix.discovery.EurekaClient");
            Object eurekaClient = applicationContext.getBean(eurekaClass);
            Method method = eurekaClass.getMethod("shutdown");
            method.invoke(eurekaClient);
            System.out.println("==================eureka down success ==============================");
        } catch (Exception ex) {
            System.out.println("EurekaClient 不存在，不用shutdown " + ex.getMessage());
            System.out.println("==================eureka down fail ==============================");
        }
    }
}
